#ifndef STACKMANAGEMENT_HPP
#define STACKMANAGEMENT_HPP

#include <QObject>
#include <QStack>
#include <QDebug>

#include "command.hpp"

/**
* @brief Class StackManagement representing the internal Stack
* @details The class provides access to the Stack \n
* Values can be pushed and popped from Stack \n
* If an overflow occures, the element at the bottom will be deleted and the new one will be added on top. \n
* As this behaviour can be explicitely wanted by developers only a Debug Message will be printed
*
* @class StackManagement stackmanagement.hpp "stackmanagement.hpp"
*/
class StackManagement : public QObject
{
Q_OBJECT

public:
    /**
    * @brief StackManagement Constructor
    *
    * @fn explicit StackManagement(QObject *parent = 0)
    * @param parent
    */
    explicit StackManagement(QObject *parent = 0);

    /**
    * @brief StackManagement Copy Constructor
    *
    * @fn StackManagement(const StackManagement &other)
    * @param other
    */
    StackManagement(const StackManagement &other);

    /**
    * @brief StackManagement Destructor
    *
    * @fn ~StackManagement()
    */
    ~StackManagement();

    /**
    * @brief Function to push a new address on top of Stack
    *
    * @fn void push(int adress)
    * @param adress
    */
    void push(int adress);

    /**
    * @brief Get the value which is Top of Stack
    *
    * @fn int pop()
    * @return int
    */
    int pop();

    /**
    * @brief Reset the Stack
    *
    * @fn void reset()
    */
    void reset();

    /**
    * @brief Return the internal data storage
    *
    * @fn const QStack<int> &getStack() const
    * @return const QStack<int>
    */
    const QStack<int> &getStack() const;

    /**
    * @brief Get the current position in Stack
    *
    * @fn int getStackPosition() const
    * @return int
    */
    int getStackPosition() const;

private:
    QStack<int> stack;
    int stackPosition;

signals:
    /**
    * @brief Signal emitted when the Stack produces an overflow
    *
    * @fn void stackOverflow()
    */
    void stackOverflow();

    /**
    * @brief Signal emitted when a new address has been pushed on the Stack
    *
    * @fn void pushStack(int adress, int level)
    * @param adress
    * @param level
    */
    void pushStack(int adress, int level);

    /**
    * @brief Signal emitted when an address has been popped from Stack
    *
    * @fn void popStack()
    */
    void popStack();
};

#endif // STACKMANAGEMENT_HPP
